#ifndef xpack_meta_has_invoke
#define xpack_meta_has_invoke
#pragma push_macro("xuser")
#undef  xuser
#define xuser mixc::meta_has_invoke::inc
#include"define/base_type.hpp"
#include"macro/xexport.hpp"
#include"macro/xforward.hpp"
#pragma pop_macro("xuser")

namespace mixc::meta_has_invoke{
    template<class callback_t, class return_t, class ... args_t>
    concept has_invoke = requires(callback_t callback, args_t ... args){
        (return_t)callback(args...);
    };

    template<class callback_t, class expected_t>
    struct meta{
        static constexpr bool result = false;
    };

    template<class callback_t, class return_t>
    struct meta<callback_t, return_t()>{
        static constexpr bool result = has_invoke<callback_t, return_t>;
    };

    template<class callback_t, class return_t, class a0_t, class ... args_t>
    struct meta<callback_t, return_t(a0_t, args_t...)>{
        static constexpr bool result = has_invoke<callback_t, return_t, a0_t, args_t...>;
    };

    template<class callback_t, class return_t, class ... args_t>
    struct meta<callback_t, return_t(*)(args_t...)> : meta<callback_t, return_t(args_t...)>{};
}

namespace mixc::meta_has_invoke::origin{
    template<class callback_t, class expected_t>
    concept has_invoke = meta<callback_t, expected_t>::result;
}

#endif

xexport_space(mixc::meta_has_invoke::origin)